import * as THREE from 'three'
import { GridHelper, SphereGeometry, MeshBasicMaterial, Mesh, RepeatWrapping, BoxGeometry } from 'three'
import { FontLoader } from 'three/examples/jsm/loaders/FontLoader.js'
import { TextGeometry } from 'three/examples/jsm/geometries/TextGeometry.js'
import Element from '../../base/Element'
import ShieldMaterial from '../../materials/ShieldMaterials'
const wordEnum = {
  五行: ['金', '木', '水', '火', '土'],
  八卦: ['乾', '坤', '震', '巽', '坎', '艮', '离', '兑'],
  数字: ['壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖', '拾'],
  天干: ['甲', '乙', '丙', '丁', '戊', '己', '庚', '辛', '壬', '癸'],
  地支: ['子', '丑', '寅', '卯', '辰', '巳', '午', '未', '申', '酉', '戌', '亥'],
  方位: ['甲', '卯', '乙', '辰', '巽', '巳', '丙', '午', '丁', '未', '坤', '申', '庚', '酉', '辛', '戍', '干', '亥', '壬', '子', '癸', '丑', '艮', '寅'],
}
const defaultOptions = {
  text: '癸',
  font: 'zhiMangXing',
  position: [0, 0, 0],
  size: 12,
  height: 2,
  curveSegments: 12,
  textFrontColor: '#FFFFFF',
  textBackColor: '#fff000',
  debug: false,
}
export default class Shield extends Element {
  constructor(options) {
    super()
    this.options = Object.assign({}, defaultOptions, options)
    this.group
    this.cannonGroup
    this.material
    this.init()
  }
  init() {
    this.createWord()
    this.options.debug && this.createDebug()
  }

  createWord() {
    this.group = new THREE.Group()
    // text
    if (!this.resource.items[this.options.font]) {
      console.warn(`throw warning: Shield Options can not find '${this.options.font}', please check.`)
    }
    let font = this.resource.items[this.options.font] ? this.resource.items[this.options.font] : this.resource.items.zhiMangXing
    const textGeom = new TextGeometry(this.options.text, {
      font: font,
      size: this.options.size,
      height: this.options.height,
      curveSegments: this.options.curveSegments,
    })
    // 文字居中
    textGeom.computeBoundingBox()
    const xOffset = (textGeom.boundingBox.max.x - textGeom.boundingBox.min.x) / 2
    const yOffset = (textGeom.boundingBox.max.y - textGeom.boundingBox.min.y) / 2
    const textMater = [new THREE.MeshStandardMaterial({ color: 0xeeed25, flatShading: true }), new THREE.MeshStandardMaterial({ color: 0x03ccbb })]
    const textMesh = new THREE.Mesh(textGeom, textMater)

    // 文字边框
    let textEdges = new THREE.EdgesGeometry(textGeom)
    let edgesMtl = new THREE.LineBasicMaterial({
      color: 0xff0000,
    })
    // // edgesMtl.depthTest = false; 深度测试，若开启则是边框透明的效果
    let textLine = new THREE.LineSegments(textEdges, edgesMtl)
    textMesh.add(textLine)

    // textMesh.position.set(-xOffset, -yOffset, 0)
    this.group.add(textMesh)
    // effect
    const texture = this.resource.items.noise
    texture.wrapS = RepeatWrapping
    texture.wrapT = RepeatWrapping
    const effectGeom = new SphereGeometry(8, 32, 32)
    const effectMater = new ShieldMaterial()
    effectMater.uniforms.uNoiseTexture.value = texture
    const effectMesh = new Mesh(effectGeom, effectMater)
    effectMesh.position.set(7, 6, 0)
    this.material = effectMater
    // this.group.add(effectMesh)
    this.group.position.set(...this.options.position)
    // 开启阴影
    // 遍历子 Mesh 开启阴影
    this.group.traverse(function (child) {
      if (child instanceof THREE.Mesh) {
        child.castShadow = true
        child.receiveShadow = true
      }
    })
    // 创建物理世界物体
    this.cannonGroup = this.cannonWorld.createMesh(this.group)
    this.scene.add(this.group)
  }

  createDebug() {
    console.log('this.group', this.group)
    const ui = this.debug.gui
    const groupFolder = ui.addFolder('天干-癸-postion')
    groupFolder.add(this.group.position, 'x')
    groupFolder.add(this.group.position, 'y')
    groupFolder.add(this.group.position, 'z')
    groupFolder.add(this.group, 'visible')
    const engergyFolder = ui.addFolder('能量盾')
    engergyFolder.addColor(this.material.uniforms.uColor, 'value').name('uColor')
    engergyFolder.add(this.material.uniforms.uThickness, 'value').min(0).max(10).step(0.01).name('uThickness')
  }

  deleteWord() {
    this.scene.remove(this.group)
    this.distoryObject(this.group, this.scene)
  }
  destoryObject(object3D, parent) {
    parent.remove(object3D)
    const children = object3D.children
    if (!children.length) {
      return
    }
    children.forEach(({ geometry, material, childrens }) => {
      geometry.dispose()
      if (Array.isArray(material)) {
        material.forEach((m) => m.dispose())
      } else {
        material?.dispose()
      }
      if (childrens && childrens.length) {
        childrens.forEach((item) => this.destoryObject(item, object3D))
      }
    })
  }

  update() {
    // console.log(this.cannonGroup)
    // this.group.position.copy(this.cannonGroup.position)
    // this.group.quaternion.copy(this.cannonGroup.quaternion)
    const { elapsed } = this.time
    // this.material.uniforms.uTime.value = elapsed
  }
}
